home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / beos / PPBeDevKit.ZIP / PLAYERPR.TAR / PlayerPRO / Source / Import-Export / MED.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-26  |  18.9 KB  |  784 lines

  1. /********************                        ***********************/
  2. //
  3. //    Player PRO 5.0 - DRIVER SOURCE CODE -
  4. //
  5. //    Library Version 5.0
  6. //
  7. //    To use with MAD Library for Mac: Symantec, CodeWarrior and MPW
  8. //
  9. //    Antoine ROSSET
  10. //    16 Tranchees
  11. //    1206 GENEVA
  12. //    SWITZERLAND
  13. //
  14. //    COPYRIGHT ANTOINE ROSSET 1996, 1997, 1998
  15. //
  16. //    Thank you for your interest in PlayerPRO !
  17. //
  18. //    FAX:                (+41 22) 346 11 97
  19. //    PHONE:             (+41 79) 203 74 62
  20. //    Internet:     RossetAntoine@bluewin.ch
  21. //
  22. /********************                        ***********************/
  23.  
  24.  
  25. #include "RDriver.h"
  26.  
  27. #if defined(powerc) || defined(__powerc)
  28. enum {
  29.         PlayerPROPlug = kCStackBased
  30.         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  31.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
  32.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( Ptr)))
  33.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( MADMusic*)))
  34.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoRec*)))
  35.         | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof( MADDriverSettings*)))
  36. };
  37.  
  38. ProcInfoType __procinfo = PlayerPROPlug;
  39. #else
  40. #include <A4Stuff.h>
  41. #endif
  42.  
  43. /**************************************************************************
  44. **************************************************************************/
  45.  
  46. #define WORD  short
  47. #define UWORD unsigned short
  48. #define ULONG unsigned long
  49. #define UBYTE Byte
  50. #define BYTE char
  51. #define BOOL Boolean 
  52.  
  53. #pragma options align=mac68k
  54.  
  55. typedef struct MMD0 {
  56.     ULONG   id;
  57.     ULONG   modlen;
  58.     ULONG   MMD0songP;              // struct MMD0song *song;
  59.     UWORD   psecnum;        /* for the player routine, MMD2 only */
  60.     UWORD   pseq;           /*  "   "   "   "    */
  61.     ULONG   MMD0BlockPP;    // struct MMD0Block **blockarr;
  62.     ULONG   reserved1;
  63.     ULONG   InstrHdrPP;             // struct InstrHdr **smplarr;
  64.     ULONG   reserved2;
  65.     ULONG   MMD0expP;               // struct MMD0exp *expdata;
  66.     ULONG   reserved3;
  67.     UWORD   pstate;                 // some data for the player routine */
  68.     UWORD   pblock;
  69.     UWORD   pline;
  70.     UWORD   pseqnum;
  71.     WORD    actplayline;
  72.     UBYTE   counter;
  73.     UBYTE   extra_songs;    /* number of songs - 1 */
  74. } MMD0;                                         /* length = 52 bytes */
  75.  
  76.  
  77. typedef struct MMD0sample {
  78.     UWORD rep,replen;       /* offs: 0(s), 2(s) */
  79.     UBYTE midich;           /* offs: 4(s) */
  80.     UBYTE midipreset;       /* offs: 5(s) */
  81.     UBYTE svol;                     /* offs: 6(s) */
  82.     BYTE strans;            /* offs: 7(s) */
  83. } MMD0sample;
  84.  
  85.  
  86. typedef struct MMD0song {
  87.     MMD0sample sample[63];  /* 63 * 8 bytes = 504 bytes */
  88.     UWORD   numblocks;      /* offs: 504 */
  89.     UWORD   songlen;        /* offs: 506 */
  90.     UBYTE   playseq[256];   /* offs: 508 */
  91.     UWORD   deftempo;       /* offs: 764 */
  92.     BYTE    playtransp;     /* offs: 766 */
  93.     UBYTE   flags;          /* offs: 767 */
  94.     UBYTE   flags2;         /* offs: 768 */
  95.     UBYTE   tempo2;         /* offs: 769 */
  96.     UBYTE   trkvol[16];     /* offs: 770 */
  97.     UBYTE   mastervol;      /* offs: 786 */
  98.     UBYTE   numsamples;     /* offs: 787 */
  99. } MMD0song;                             /* length = 788 bytes */
  100.  
  101.  
  102. typedef struct MMD0NOTE{
  103.     UBYTE a,b,c;
  104. } MMD0NOTE;
  105.  
  106.  
  107. typedef struct MMD1NOTE{
  108.     UBYTE a,b,c,d;
  109. } MMD1NOTE;
  110.  
  111.  
  112. typedef struct InstrHdr {
  113.         ULONG   length;
  114.         WORD    type;
  115.         /* Followed by actual data */
  116. } InstrHdr;
  117.  
  118. #pragma options align=reset
  119.  
  120. /**************************************************************************
  121. **************************************************************************/
  122.  
  123. static MMD0         *mh;
  124. static MMD0song     *ms;
  125. static ULONG         *ba;
  126.  
  127. static MMD0NOTE     *mmd0pat;
  128. static MMD1NOTE     *mmd1pat;
  129.  
  130. #define d0note(row,col) mmd0pat[(row*(UWORD) theMAD->header->numChn)+col]
  131.  
  132. #define d1note(row,col) mmd1pat[(row*(UWORD) theMAD->header->numChn)+col]
  133.  
  134.  
  135. static Ptr            theMEDRead;
  136. #define READMEDFILE(dst, size)    {BlockMove( theMEDRead, dst, size);    theMEDRead += (long) size;}
  137.  
  138. Ptr MADPlugNewPtr( long size, MADDriverSettings* init)
  139. {
  140.     if( init->sysMemory) return NewPtrSys( size);
  141.     else return NewPtr( size);
  142. }
  143.  
  144. Ptr MADPlugNewPtrClear( long size, MADDriverSettings* init)
  145. {
  146.     if( init->sysMemory) return NewPtrSysClear( size);
  147.     else return NewPtrClear( size);
  148. }
  149.  
  150. Cmd* GetMADCommand( register short PosX, register short    TrackIdX, register PatData*    tempMusicPat)
  151. {
  152.     if( PosX < 0) PosX = 0;
  153.     else if( PosX >= tempMusicPat->header.size) PosX = tempMusicPat->header.size -1;
  154.         
  155.     return( & (tempMusicPat->Cmds[ (tempMusicPat->header.size * TrackIdX) + PosX]));
  156. }
  157.  
  158. void pStrcpy(register unsigned char *s1, register unsigned char *s2)
  159. {
  160.     register short len, i;
  161.     
  162.     len = *s2;
  163.     for ( i = 0; i <= len; i++) s1[ i] = s2[ i];
  164. }
  165.  
  166. void mystrcpy( Ptr a, Ptr b)
  167. {
  168.     BlockMove( b + 1, a, b[ 0]);
  169. }
  170.  
  171. BOOL MED_Init( MADDriverSettings *init)
  172. {
  173.     mh=NULL;
  174.     ms=NULL;
  175.     ba=NULL;        // blockarr
  176.     mmd0pat=NULL;
  177.     mmd1pat=NULL;
  178.  
  179.     if(!(mh=(MMD0 *) MADPlugNewPtr( sizeof(MMD0), init))) return 0;
  180.     if(!(ms=(MMD0song *) MADPlugNewPtr( sizeof(MMD0song), init))) return 0;
  181.     return 1;
  182. }
  183.  
  184. void MED_Cleanup(void)
  185. {
  186.     if(mh!=NULL) DisposePtr( (Ptr) mh);
  187.     if(ms!=NULL) DisposePtr( (Ptr) ms);
  188.     if(ba!=NULL) DisposePtr( (Ptr) ba);
  189.  
  190.     if(mmd0pat!=NULL) DisposePtr( (Ptr) mmd0pat);
  191.     if(mmd1pat!=NULL) DisposePtr( (Ptr) mmd1pat);
  192. }
  193.  
  194. void EffectCvt( UBYTE eff, UBYTE dat, Cmd *aCmd)
  195. {
  196.     switch(eff){
  197.  
  198.         // 0x0 0x1 0x2 0x3 0x4      // PT effects
  199.  
  200.         case 0x5:       // PT vibrato with speed/depth nibbles swapped
  201.             aCmd->cmd = 4;
  202.             aCmd->arg = (dat>>4) | ((dat&0xf)<<4);
  203.             break;
  204.  
  205.         case 0x6:       // not used
  206.         case 0x7:       // not used
  207.         case 0x8:       // midi hold/decay
  208.             break;
  209.  
  210.         case 0x9:
  211.             if(dat<=0x20)
  212.             {
  213.                 aCmd->cmd = 0xf;
  214.                 aCmd->arg = dat;
  215.             }
  216.             break;
  217.  
  218.         // 0xa 0xb 0xc all PT effects
  219.  
  220.         case 0xd:       // same as PT volslide
  221.             aCmd->cmd = 0xa;
  222.             aCmd->arg = dat;
  223.             break;
  224.  
  225.         case 0xe:       // synth jmp - midi
  226.             break;
  227.  
  228.         case 0xf:
  229.  
  230.             // F00 does patternbreak with med
  231.  
  232.             if(dat==0)
  233.             {
  234.                 aCmd->cmd = 0xd;
  235.                 aCmd->arg = 0;
  236.             }
  237.             else if(dat<=0xa)
  238.             {
  239.                 aCmd->cmd = 0xf;
  240.                 aCmd->arg = dat;
  241.             }
  242.             else if(dat<0xf1)
  243.             {
  244.                 aCmd->cmd = 0xf;
  245.                 aCmd->arg = ((long)dat*125L)/33L;
  246.             }
  247.             else if(dat==0xff)
  248.             {
  249.                 // stop note
  250.                 aCmd->note = 0xFE;
  251.             }
  252.             break;
  253.  
  254.         default:        // all normal PT effects are handled here :)
  255.             aCmd->cmd = eff;
  256.             aCmd->arg = dat;
  257.             break;
  258.     }
  259. }
  260.  
  261. void MED_Convert1( short col, short patID, MADMusic *theMAD)
  262. {
  263.     int t;
  264.     UBYTE a,b,c,d,inst,note,eff,dat;
  265.     MMD1NOTE *n;
  266.     Cmd    *aCmd;
  267.  
  268.     for(t=0;t<theMAD->partition[ patID]->header.size;t++){
  269.  
  270.         n= &d1note(t,col);
  271.  
  272.         a = n->a;
  273.         b = n->b;
  274.         c = n->c;
  275.         d = n->d;
  276.  
  277.         note=a&0x7f;
  278.         inst=b&0x3f;
  279.         eff=c&0xf;
  280.         dat=d;
  281.  
  282.         aCmd = GetMADCommand( t, col, theMAD->partition[ patID]);
  283.  
  284.         aCmd->ins     = inst;
  285.         if(note != 0)
  286.         {
  287.             aCmd->note = note+35;
  288.         }
  289.         else aCmd->note = 0xFF;
  290.  
  291.         aCmd->cmd     = 0;
  292.         aCmd->arg     = 0;
  293.         aCmd->vol    = 0xFF;
  294.  
  295.         EffectCvt( eff, dat, aCmd);
  296.     }
  297. }
  298.  
  299.  
  300.  
  301. void MED_Convert0( short patID, MADMusic *theMAD)
  302. {
  303.     int         t, zz;
  304.     UBYTE         a,b,c,inst,note,eff,dat, temp;
  305.     MMD0NOTE     *n;
  306.     Cmd            *aCmd;
  307.  
  308.     for( t = 0 ; t < theMAD->partition[ patID]->header.size; t++)
  309.     {
  310.         for( zz = 0 ; zz < theMAD->header->numChn; zz++)
  311.         {
  312.             n= &d0note( t, zz);
  313.             
  314.             a = n->a;
  315.             b = n->b;
  316.             c = n->c;
  317.             
  318.             note    =        a&0x3f;
  319.             
  320.             a        >>=        6;
  321.             a        =        ((a&1)<<1)|(a>>1);
  322.             
  323.             inst    =        (b>>4)|(a<<4);
  324.             eff        =        b&0xf;
  325.             dat        =        c;
  326.             
  327.             aCmd = GetMADCommand( t, zz, theMAD->partition[ patID]);
  328.             
  329.             aCmd->ins     = inst;
  330.             
  331.             if(note != 0)
  332.             {
  333.                 aCmd->note = note+35;
  334.             }
  335.             else aCmd->note = 0xFF;
  336.             
  337.             aCmd->cmd     = 0;
  338.             aCmd->arg     = 0;
  339.             aCmd->vol    = 0xFF;
  340.             
  341.             EffectCvt( eff, dat, aCmd);
  342.         }
  343.     }
  344. }
  345.  
  346. OSErr LoadMMD0Patterns( MADMusic *theMAD, Ptr theMED, MADDriverSettings *init)
  347. {
  348.     int         t,row,col;
  349.     UWORD         numtracks,numlines,maxlines=0;
  350.     char        tC;
  351.     long        x;
  352.     
  353.     // first, scan patterns to see how many channels are used
  354.  
  355.     for( t = 0; t < theMAD->header->numPat; t++)
  356.     {
  357.         theMEDRead = theMED + ba[ t];
  358.         READMEDFILE( &tC, sizeof( char));    numtracks = tC;
  359.         READMEDFILE( &tC, sizeof( char));    numlines = tC;
  360.         
  361.         if(numtracks > theMAD->header->numChn) theMAD->header->numChn = numtracks;
  362.         if(numlines  > maxlines) maxlines = numlines;
  363.     }
  364.     
  365.     mmd0pat = (MMD0NOTE *) MADPlugNewPtrClear( theMAD->header->numChn * (maxlines+1) * sizeof(MMD0NOTE), init);
  366.     if( mmd0pat == 0L) Debugger();
  367.     
  368.     /* second read: no more mr. nice guy,
  369.        really read and convert patterns */
  370.  
  371.     for( t = 0 ; t < theMAD->header->numPat; t++)
  372.     {
  373.         theMEDRead = theMED + ba[ t];
  374.         READMEDFILE( &tC, sizeof( char));    numtracks = tC;
  375.         READMEDFILE( &tC, sizeof( char));    numlines = tC;
  376.         
  377.         numlines++;
  378.         
  379.         theMAD->partition[ t] = (PatData*) MADPlugNewPtrClear( sizeof( PatHeader) + theMAD->header->numChn * numlines * sizeof( Cmd), init);
  380.         if( theMAD->partition[ t] == 0L) return MADNeedMemory;
  381.         
  382.         theMAD->partition[ t]->header.size         = numlines;
  383.         theMAD->partition[ t]->header.compMode     = 'NONE';
  384.         
  385.         for( x = 0; x < 20; x++) theMAD->partition[ t]->header.name[ x] = 0;
  386.         
  387.         theMAD->partition[ t]->header.patBytes = 0L;        theMAD->partition[ t]->header.unused2 = 0L;
  388.     
  389.         //memset( mmd0pat, 0, of.numchn * maxlines * sizeof(MMD0NOTE));
  390.         
  391.         for( x = 0; x < theMAD->header->numChn * maxlines * sizeof(MMD0NOTE); x++)
  392.         {
  393.             ((Ptr) mmd0pat)[ x] = 0;
  394.         }
  395.         
  396.         for( row = 0 ; row < numlines; row++)
  397.         {
  398.             short ztz;
  399.             
  400.             for( ztz = 0; ztz < numtracks; ztz++)
  401.                 READMEDFILE( &d0note( row, ztz), 3);        // sizeof(MMD0NOTE) != 3 probleme compilation alignement
  402.         }
  403.         
  404.         MED_Convert0( t, theMAD);
  405.     }
  406.     
  407.     return noErr;
  408. }
  409.  
  410. OSErr LoadMMD1Patterns( MADMusic *theMAD, Ptr theMED, MADDriverSettings *init)
  411. {
  412.     int t,row,col;
  413.     UWORD numtracks,numlines,maxlines=0,track=0;
  414.     long    x;
  415.  
  416.     // first, scan patterns to see how many channels are used
  417.  
  418.     for( t = 0 ; t < theMAD->header->numPat; t++)
  419.     {
  420.         theMEDRead = theMED + ba[ t];
  421.         READMEDFILE( &numtracks, sizeof( short));
  422.         READMEDFILE( &numlines, sizeof( short));
  423.         
  424.         if( numtracks > theMAD->header->numChn) theMAD->header->numChn = numtracks;
  425.         if( numlines  > maxlines) maxlines = numlines;
  426.  
  427.         if( numlines > 999)
  428.         {
  429.             DebugStr("\pCan't load patterns > 999 rows");
  430.             return -1;
  431.         }
  432.     }
  433.     
  434.     mmd1pat = (MMD1NOTE *) MADPlugNewPtrClear( theMAD->header->numChn * (maxlines+1) * sizeof( MMD1NOTE), init);
  435.     if( mmd1pat == 0L) Debugger();
  436.     
  437.     /* second read: no more mr. nice guy,
  438.        really read and convert patterns */
  439.  
  440.     for(t=0;t<theMAD->header->numPat;t++){
  441.  
  442.         theMEDRead = theMED + ba[ t];
  443.         READMEDFILE( &numtracks, sizeof( short));
  444.         READMEDFILE( &numlines, sizeof( short));
  445.         
  446.         theMEDRead += 4L;
  447.         
  448.         numlines++;
  449.         
  450.         theMAD->partition[ t] = (PatData*) MADPlugNewPtrClear( sizeof( PatHeader) + theMAD->header->numChn * numlines * sizeof( Cmd), init);
  451.         if( theMAD->partition[ t] == 0L) return MADNeedMemory;
  452.         
  453.         theMAD->partition[ t]->header.size         = numlines;
  454.         theMAD->partition[ t]->header.compMode     = 'NONE';
  455.         
  456.         for( x = 0; x < 20; x++) theMAD->partition[ t]->header.name[ x] = 0;
  457.         
  458.         theMAD->partition[ t]->header.patBytes = 0L;        theMAD->partition[ t]->header.unused2 = 0L;
  459.  
  460.  
  461.  
  462.         for( x = 0; x < theMAD->header->numChn * maxlines * sizeof(MMD0NOTE); x++)
  463.         {
  464.             ((Ptr) mmd1pat)[ x] = 0;
  465.         }
  466.  
  467.         for( row = 0 ; row < numlines ; row++)
  468.         {
  469.             READMEDFILE( &d1note( row, 0), sizeof(MMD1NOTE) * numtracks);
  470.         }
  471.  
  472.         for(col=0;col< theMAD->header->numChn;col++)
  473.         {
  474.             MED_Convert1( col, t, theMAD);
  475.             track++;
  476.         }
  477.     }
  478.  
  479.     return noErr;
  480. }
  481.  
  482. OSErr MED_Load( Ptr    theMED, long MEDSize, MADMusic *theMAD, MADDriverSettings *init)
  483. {
  484.     int         t, i;
  485.     ULONG         sa[64];
  486.     InstrHdr     s;
  487.     long        inOutCount;
  488.  
  489.     theMEDRead = theMED;
  490.  
  491.     /*********************/
  492.     /** READ MED HEADER **/
  493.     /*********************/
  494.     
  495.     READMEDFILE( mh, sizeof(MMD0));
  496.  
  497.     /**************************/
  498.     /** READ MMD0song struct **/
  499.     /**************************/
  500.     
  501.     theMEDRead = theMED + mh->MMD0songP;
  502.     READMEDFILE( ms, sizeof(MMD0song));
  503.  
  504.     /***************************/
  505.     /** READ SamplePtr struct **/
  506.     /***************************/
  507.     
  508.     theMEDRead = theMED + mh->InstrHdrPP;
  509.     READMEDFILE( sa, sizeof(ULONG)*ms->numsamples);
  510.  
  511.     /***************************/
  512.     /**    BLOCK PTR ARRAY    **/
  513.     /***************************/
  514.  
  515.     ba = (ULONG*) MADPlugNewPtrClear( ms->numblocks * sizeof(ULONG), init);
  516.     if( ba == 0L) return MADNeedMemory;
  517.     
  518.     theMEDRead = theMED + mh->MMD0BlockPP;
  519.     READMEDFILE( ba, sizeof(ULONG)*ms->numblocks);
  520.     
  521.     
  522.     /********************/
  523.     /********************/
  524.     /** MAD ALLOCATION **/
  525.     /********************/
  526.     /********************/
  527.     
  528.     inOutCount = sizeof( MADSpec);
  529.     theMAD->header = (MADSpec*) MADPlugNewPtrClear( inOutCount, init);    
  530.     if( theMAD->header == 0L) DebugStr("\pHeader: I NEED MEMORY !!! NOW !");
  531.     
  532.     theMAD->header->MAD = 'MADI';
  533.     
  534.     mystrcpy( theMAD->header->infos, (Ptr) "\pConverted by PlayerPRO MED Plug (⌐Antoine ROSSET <rossetantoine@bluewin.ch>)");
  535.     
  536.     theMAD->header->speed            =     ms->tempo2;
  537.     theMAD->header->tempo            =    ((long)ms->deftempo * 125L) / 33L;
  538.     theMAD->header->numChn            =    0;        // will be counted later
  539.     theMAD->header->numPat            =    ms->numblocks;
  540.     theMAD->header->numPointers        =    ms->songlen;
  541.     if( ms->numsamples >= MAXINSTRU) ms->numsamples = MAXINSTRU-1;
  542.     
  543.     if( theMAD->header->numPointers > 128) theMAD->header->numPointers = 128;
  544.     
  545.     for( i = 0; i < ms->songlen; i++)
  546.     {
  547.         theMAD->header->oPointers[ i] = ms->playseq[ i];
  548.         if( theMAD->header->oPointers[ i] >= theMAD->header->numPat)
  549.             theMAD->header->oPointers[ i] = theMAD->header->numPat-1;
  550.     }
  551.  
  552. for( i = 0; i < MAXTRACK; i++)
  553. {
  554.     if( i % 2 == 0) theMAD->header->chanPan[ i] = MAX_PANNING/4;
  555.     else theMAD->header->chanPan[ i] = MAX_PANNING - MAX_PANNING/4;
  556.     
  557.     theMAD->header->chanVol[ i] = MAX_VOLUME;
  558. }
  559.  
  560.     theMAD->header->generalVol        = 64;
  561.     theMAD->header->generalSpeed    = 80;
  562.     theMAD->header->generalPitch    = 80;
  563.  
  564.     /***************************/
  565.     /**      SAMPLES INS      **/
  566.     /***************************/
  567.  
  568.     theMAD->fid = ( InstrData*) MADPlugNewPtrClear( sizeof( InstrData) * (long) MAXINSTRU, init);
  569.     if( !theMAD->fid) return MADNeedMemory;
  570.     
  571.     theMAD->sample = ( sData**) MADPlugNewPtrClear( sizeof( sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, init);
  572.     if( !theMAD->sample) return MADNeedMemory;
  573.     
  574.     for( i = 0; i < MAXINSTRU; i++) theMAD->fid[ i].firstSample = i * MAXSAMPLE;
  575.     
  576.     for( t = 0 ; t < ms->numsamples ; t++)
  577.     {
  578.         theMEDRead = theMED + sa[ t];
  579.         READMEDFILE( &s, sizeof(InstrHdr));
  580.         
  581.         theMAD->fid[ t].type = 0;
  582.         
  583.         if( s.length > 0 && s.length < 0x4d4d4430)
  584.         {
  585.             sData    *curData;
  586.             
  587.             theMAD->fid[ t].numSamples = 1;
  588.             theMAD->fid[ t].volFade = DEFAULT_VOLFADE;
  589.             
  590.             curData = theMAD->sample[ t*MAXSAMPLE + 0] = (sData*) MADPlugNewPtrClear( sizeof( sData), init);
  591.             
  592.             curData->size        = s.length;
  593.             curData->loopBeg     = ms->sample[t].rep<<1;
  594.             curData->loopSize     = curData->loopBeg + (ms->sample[ t].replen<<1);
  595.             if( curData->loopBeg + curData->loopSize > curData->size)
  596.             {
  597.                 curData->loopSize = curData->size - curData->loopBeg;
  598.             }
  599.             curData->vol        = 64;
  600.             curData->c2spd        = NOFINETUNE;
  601.             curData->loopType    = 0;
  602.             curData->amp        = 8;
  603.             
  604.             curData->relNote    = 0;
  605.             
  606.             curData->data         = MADPlugNewPtr( curData->size, init);
  607.             if( curData->data == 0L) return MADNeedMemory;
  608.             
  609.             READMEDFILE( curData->data, curData->size);
  610.         }
  611.         else theMAD->fid[ t].numSamples = 0;
  612.     }
  613.     
  614.     /***************************/
  615.     /**       PATTERNS        **/
  616.     /***************************/
  617.     
  618.     switch( mh->id)
  619.     {
  620.         case 'MMD0':
  621.             if( LoadMMD0Patterns( theMAD, theMED, init) != noErr) return MADUnknowErr;
  622.         break;
  623.         
  624.         case 'MMD1':
  625.             if( LoadMMD1Patterns( theMAD, theMED, init) != noErr) return MADUnknowErr;
  626.         break;
  627.     }
  628.     
  629.     return noErr;
  630. }
  631.  
  632. Boolean compMem( Ptr a, Ptr b, long s)
  633. {
  634. long     i;
  635.  
  636.     for( i = 0; i < s; i++)
  637.     {
  638.         if( a[ i] != b[ i]) return false;
  639.     }
  640.     
  641.     return true;
  642. }
  643.  
  644. OSErr TestMEDFile( Ptr AlienFile)
  645. {
  646.     if( compMem( AlienFile, "MMD0", 4) == false && compMem( AlienFile, "MMD1", 4) == false) return MADFileNotSupportedByThisPlug;
  647.     else return noErr;
  648. }
  649.  
  650. OSErr ExtractMEDInfo( PPInfoRec *info, Ptr theMED)
  651. {
  652.     long    PatternSize;
  653.     short    i;
  654.     short    maxInstru;
  655.     short    tracksNo;
  656.     long    inOutCount;
  657.     
  658.     theMEDRead = theMED;
  659.  
  660.     READMEDFILE( mh, sizeof(MMD0));
  661.     
  662.     theMEDRead = theMED + mh->MMD0songP;
  663.     READMEDFILE( ms, sizeof(MMD0song));
  664.  
  665.     info->signature = mh->id;
  666.     
  667.     MADstrcpy( info->internalFileName, "");
  668.     
  669.     info->totalPatterns = ms->numblocks;
  670.     info->partitionLength = ms->songlen;
  671.     info->totalInstruments = ms->numsamples;
  672.     info->totalTracks = 0;
  673.     
  674.     MADstrcpy( info->formatDescription, "MED Plug");
  675.     
  676.     return noErr;
  677. }
  678.  
  679. OSErr main( OSType order, char *AlienFileName, MADMusic *MadFile, PPInfoRec *info, MADDriverSettings *init)
  680. {
  681.     OSErr    myErr;
  682.     Ptr        AlienFile;
  683.     short    vRefNum, iFileRefI;
  684.     long    dirID, sndSize;
  685.     
  686. #ifndef powerc
  687.     long    oldA4 = SetCurrentA4();             //this call is necessary for strings in 68k code resources
  688. #endif
  689.  
  690.     c2pstr( AlienFileName);
  691.     
  692.     myErr = noErr;
  693.  
  694.     MED_Init( init);
  695.  
  696.     switch( order)
  697.     {
  698.         case 'IMPL':
  699.             myErr = FSOpen( (unsigned char*) AlienFileName, 0, &iFileRefI);
  700.             if( myErr == noErr)
  701.             {
  702.                 GetEOF( iFileRefI, &sndSize);
  703.             
  704.                 // ** MEMORY Test Start
  705.                 AlienFile = MADPlugNewPtr( sndSize * 2L, init);
  706.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  707.                 // ** MEMORY Test End
  708.                 
  709.                 else
  710.                 {
  711.                     DisposePtr( AlienFile);
  712.                     
  713.                     AlienFile = MADPlugNewPtr( sndSize, init);
  714.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  715.                     if( myErr == noErr)
  716.                     {
  717.                         myErr = TestMEDFile( AlienFile);
  718.                         if( myErr == noErr)
  719.                         {
  720.                             myErr = MED_Load( AlienFile,  GetPtrSize( AlienFile), MadFile, init);
  721.                         }
  722.                     }
  723.                     DisposePtr( AlienFile);    AlienFile = 0L;
  724.                 }
  725.                 FSClose( iFileRefI);
  726.             }
  727.         break;
  728.         
  729.         case 'TEST':
  730.             myErr = FSOpen( (unsigned char*) AlienFileName, 0, &iFileRefI);
  731.             if( myErr == noErr)
  732.             {
  733.                 sndSize = 1024L;
  734.                 
  735.                 AlienFile = MADPlugNewPtr( sndSize, init);
  736.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  737.                 else
  738.                 {
  739.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  740.                     myErr = TestMEDFile( AlienFile);
  741.                     
  742.                     DisposePtr( AlienFile);    AlienFile = 0L;
  743.                 }
  744.                 FSClose( iFileRefI);
  745.             }
  746.         break;
  747.  
  748.         case 'INFO':
  749.             myErr = FSOpen( (unsigned char*) AlienFileName, 0, &iFileRefI);
  750.             if( myErr == noErr)
  751.             {
  752.                 GetEOF( iFileRefI, &info->fileSize);
  753.             
  754.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  755.                 
  756.                 AlienFile = MADPlugNewPtr( sndSize, init);
  757.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  758.                 else
  759.                 {
  760.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  761.                     if( myErr == noErr)
  762.                     {
  763.                         myErr = ExtractMEDInfo( info, AlienFile);
  764.                     }
  765.                     DisposePtr( AlienFile);    AlienFile = 0L;
  766.                 }
  767.                 FSClose( iFileRefI);
  768.             }
  769.         break;
  770.         
  771.         default:
  772.             myErr = MADOrderNotImplemented;
  773.         break;
  774.     }
  775.  
  776.     MED_Cleanup();
  777.  
  778.     p2cstr( (unsigned char*) AlienFileName);
  779.     
  780.     #ifndef powerc
  781.         SetA4( oldA4);
  782.     #endif
  783.     return myErr;
  784. }